#include "cam_controller_kb.h"
#include "abstract_camera.h"

//#include "font/font_manager.h"
#include "math/vec3.h"

#include "util/timer.h"		// macros
#include "util/common_macros.h"		// macros
#include "util/log.h"		// macros
#include "util/mmgr.h"		// Needs to come in early

#include <cassert>


using namespace std;

using namespace camera;

CamControllerKB::CamControllerKB() :
	input::KeyboardListener(),		
	CamController()
{
}

CamControllerKB::~CamControllerKB()
{

}

void CamControllerKB::Tick(AbstractCamera* _pCam, float dt)
{
    assert(_pCam && "Invalid camera passed to Camera Controller");

    float       CamMoveSpeed = 100.0f * dt;
    float       CamTurnSpeed = 1.0f * dt;

	// Update camera position ?
	if (m_Move.MagSqr() > 0.0f)
	{
		// Move
        math::Vec3  Delta = ( CamMoveSpeed * _pCam->GetDir()   * m_Move.y) + 
						    ( CamMoveSpeed * _pCam->GetRight() * m_Move.x);
        math::Vec3  Pos	  = _pCam->GetPos() + Delta;
        _pCam->SetLookAt(Pos, Pos + _pCam->GetDir(), _pCam->GetUp());
	}

	// Update camera rotation
	if (m_Turn.MagSqr() > 0.0f)
	{
        math::Vec3 Turn	=	(CamTurnSpeed * _pCam->GetRight() * m_Turn.x) + 
							(CamTurnSpeed * _pCam->GetUp() *    -m_Turn.y);

        math::Vec3  Pos	= _pCam->GetPos();
        math::Vec3  To  = Pos + _pCam->GetDir() + Turn;
        _pCam->SetLookAt(Pos, To, _pCam->GetUp());
	}

    // reset vectors for next time
    m_Move = math::Vec2();
    m_Turn = math::Vec2();
}   

void CamControllerKB::KeyDown(input::Keyboard::KEY* pKey)
{
	switch(pKey->KeyID)
	{
		// movement
		case KEY_A:
		    m_Move.x = -1;
		break;
		case KEY_D:
		    m_Move.x = 1;
		break;
		case KEY_W:
		    m_Move.y = 1;
		break;
		case KEY_S:
		    m_Move.y = -1;
		break;

		// turning
		case KEY_LEFT:
		    m_Turn.x = -1;
		break;
		case KEY_RIGHT:
		    m_Turn.x = 1;
		break;
		case KEY_UP:
		    m_Turn.y = 1;		
			break;
		case KEY_DOWN:
		    m_Turn.y = -1;
		break;

	}
	
}
